package org.easy.mybatis.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.shiro.SecurityUtils;
import org.easy.common.generator.SnowflakeIdWorker;
import org.easy.common.util.ConvertUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.Properties;

/**
 * @ClassName: MybatisInterceptor
 * @Description: mybatis拦截器（负责添加、修改时的字段默认赋值处理）
 * @Author zhouzhixin
 * @Date 2021/10/12
 * @Version 1.0
 */
/*
@Slf4j
@Component
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class MybatisInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        String sqlId = mappedStatement.getId();
        log.debug("------sqlId------" + sqlId);
        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
        Object parameter = invocation.getArgs()[1];
        log.debug("------sqlCommandType------" + sqlCommandType);

        if (parameter == null) {
            return invocation.proceed();
        }
        if (SqlCommandType.INSERT == sqlCommandType) {
            Field[] fields = ConvertUtils.getAllFields(parameter);
            for (Field field : fields) {
                log.debug("------field.name------" + field.getName());
                try {
                    // 获取登录用户信息
                    String username = null;
                    try {
                        username = (String) SecurityUtils.getSubject().getPrincipal();
                    } catch (Exception ignored) {
                    }
                    // mybatis添加时所处理的逻辑内容
                    if ("id".equals(field.getName())) {
                        field.setAccessible(true);
                        Object local_id = field.get(parameter);
                        field.setAccessible(false);
                        if (local_id == null || local_id.equals("")) {
                            String id = SnowflakeIdWorker.generateId().toString();
                            if (ConvertUtils.isNotEmpty(id)) {
                                field.setAccessible(true);
                                field.set(parameter, id);
                                field.setAccessible(false);
                            }
                        }
                    }
                    if ("createBy".equals(field.getName())) {
                        field.setAccessible(true);
                        Object local_createBy = field.get(parameter);
                        field.setAccessible(false);
                        if (local_createBy == null || local_createBy.equals("")) {
                            String createBy = "system";
                            if (username != null) {
                                // 登录账号
                                createBy = username;
                            }
                            if (ConvertUtils.isNotEmpty(createBy)) {
                                field.setAccessible(true);
                                field.set(parameter, createBy);
                                field.setAccessible(false);
                            }
                        }
                    }
                    if ("createTime".equals(field.getName())) {
                        field.setAccessible(true);
                        Object local_createDate = field.get(parameter);
                        field.setAccessible(false);
                        if (local_createDate == null || local_createDate.equals("")) {
                            field.setAccessible(true);
                            field.set(parameter, new Date());
                            field.setAccessible(false);
                        }
                    }
                    if ("deleted".equals(field.getName())) {
                        field.setAccessible(true);
                        Object local_deleted = field.get(parameter);
                        field.setAccessible(false);
                        if (local_deleted == null || local_deleted.equals("")) {
                            field.setAccessible(true);
                            field.set(parameter, "0");
                            field.setAccessible(false);
                        }
                    }
                    // 序号字段不允许带入更新或插入语句，此处清除条件
                } catch (Exception ignored) {
                }
            }
        }
        if (SqlCommandType.UPDATE == sqlCommandType) {
            Field[] fields;
            if (parameter instanceof MapperMethod.ParamMap) {
                MapperMethod.ParamMap<?> p = (MapperMethod.ParamMap<?>) parameter;
                // 批量更新报错---start
                if (p.containsKey("et")) {
                    parameter = p.get("et");
                } else {
                    parameter = p.get("param1");
                }
                // 批量更新报错---end

                // 更新指定字段时报错---start
                if (parameter == null) {
                    return invocation.proceed();
                }
                // 更新指定字段时报错---end

                fields = ConvertUtils.getAllFields(parameter);
            } else {
                fields = ConvertUtils.getAllFields(parameter);
            }

            for (Field field : fields) {
                log.debug("------field.name------" + field.getName());
                try {
                    // mybatis更新时所处理的逻辑内容
                    if ("updateBy".equals(field.getName())) {
                        //获取登录用户信息
                        String username = (String) SecurityUtils.getSubject().getPrincipal();
                        if (username == null) {
                            username = "system";
                        }
                        // 登录账号
                        field.setAccessible(true);
                        field.set(parameter, username);
                        field.setAccessible(false);
                    }
                    if ("updateTime".equals(field.getName())) {
                        field.setAccessible(true);
                        field.set(parameter, new Date());
                        field.setAccessible(false);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // Auto-generated method stub
    }

}*/
